package jvm

//
//import (
//	"errors"
//	"github.com/ethereum/go-ethereum/rlp"
//	"github.com/golang/protobuf/proto"
//	"hundsun.com/hsl/hschain/protos/common"
//	"hundsun.com/hsl/hschain/protos/ledger"
//	"hundsun.com/hsl/hschain/store/extend/contract"
//	"regexp"
//	"strconv"
//	"strings"
//)
//
//func checkContract(code []byte) (bool, ChkCodeErrCode, string) {
//	return w.jvmIns.CheckContract(code)
//}
//func checkContractVersionFormat(ver string) bool {
//	//检查格式是否正确XXX.XXX.XXX
//	matchRet, err := regexp.MatchString(`(0|[1-9]{0,3})\.(0|[1-9]{0,3})\.(0|[1-9]{0,3})`, ver)
//	if err != nil {
//		return false
//	}
//	return matchRet
//}
//
////比较合约版本号，ver < otherVer ? false:true
//func contractVersionCompare(ver string, otherVer string) bool {
//	newVers := strings.Split(ver, ".")
//	oldVers := strings.Split(otherVer, ".")
//	var newVersionNumber uint32
//	var oldVersionNumber uint32
//	for i := 0; i < 3; i++ {
//		nn, _ := strconv.ParseFloat(newVers[i], 16)
//		no, _ := strconv.ParseFloat(oldVers[i], 16)
//		if i == 0 {
//			newVersionNumber = uint32(nn)
//			oldVersionNumber = uint32(no)
//		} else {
//			newVersionNumber = newVersionNumber*1000 + uint32(nn)
//			oldVersionNumber = oldVersionNumber*1000 + uint32(no)
//		}
//	}
//	if newVersionNumber < oldVersionNumber {
//		return false
//	}
//	return true
//}
//
////更改合约状态
//func updateContractState(tx *ledger.Transaction, ctx *VMRunContext) error {
//	log := w.log
//	//获取智能合约地址contractId+version
//	ctAddr := tx.GetContractAddressById()
//	ctNewState := string(tx.Payload)
//	ctIns := contract.GetContractInstance()
//	ct, _ := ctIns.GetContract(ctAddr)
//	if ct == nil {
//		log.Errorf("contract %s not exist when update state to %s", ctAddr, ctNewState)
//		ctx.GroupedTx.TxExecRst.Receipt.TxStatus = ledger.TransactionReceipt_CONTRACT_ACCOUNT_NOT_EXSIT
//		return errors.New("contract not exist")
//	}
//	oldState := common.ContractVersion_NORMAL
//	newState := common.ContractVersion_NORMAL
//	lastVersion := ""
//	var managerList []string
//	if _, ok := ctx.PreState.NsKVMp[tx.ContractId.Name]; ok {
//		if stateBytes, ok := ctx.PreState.NsKVMp[tx.ContractId.Name][ContractVersionSpace+"State"]; ok {
//			oldState = common.ContractVersion_ContractState(stateBytes.Value[0])
//		}
//		if ver, ok := ctx.PreState.NsKVMp[tx.ContractId.Name][ContractVersionSpace+"LastVersion"]; ok {
//			lastVersion = string(ver.Value)
//		}
//		if mgrs, ok := ctx.PreState.NsKVMp[tx.ContractId.Name][ContractVersionSpace+"ManagerList"]; ok {
//			managerList = strings.Split(string(mgrs.Value), ",")
//		}
//	}
//	//更新合约状态
//	if ctNewState == "PAUSE" {
//		if oldState == common.ContractVersion_NORMAL {
//			newState = common.ContractVersion_PAUSED
//		} else {
//			ctx.GroupedTx.TxExecRst.Receipt.TxStatus = ledger.TransactionReceipt_CONTRACT_STATE_NOT_NORMAL
//			return errors.New("contract old state is not normal")
//		}
//	} else if ctNewState == "RESUME" {
//		if oldState == common.ContractVersion_PAUSED {
//			newState = common.ContractVersion_NORMAL
//		} else {
//			ctx.GroupedTx.TxExecRst.Receipt.TxStatus = ledger.TransactionReceipt_CONTRACT_STATE_NOT_NORMAL
//			return errors.New("contract old state is not paused")
//		}
//	} else if ctNewState == "STOP" {
//		newState = common.ContractVersion_STOPED
//	} else {
//		ctx.GroupedTx.TxExecRst.Receipt.TxStatus = ledger.TransactionReceipt_CONTRACT_STATE_NOT_NORMAL
//		return errors.New("not known contract state")
//	}
//	//状态没有发生改变
//	if oldState == newState {
//		return nil
//	}
//
//	ctVer := &common.ContractVersion{Name: tx.ContractId.Name, LastVersion: lastVersion, State: newState, ManagerList: managerList}
//	ctVerBytes, err := proto.Marshal(ctVer)
//	if err == nil && ctVerBytes != nil && len(ctVerBytes) > 0 {
//		nskv := &ledger.NsKV{Namespace: ContractVersionSpace, Key: tx.ContractId.Name, Value: ctVerBytes}
//		ctx.GroupedTx.TxExecRst.KvWrites = append(ctx.GroupedTx.TxExecRst.KvWrites, nskv)
//	}
//	stateBytes := make([]byte, 1)
//	verNskv := &ledger.NsKV{Namespace: ContractVersionSpace, Key: "State", Value: stateBytes}
//	if _, ok := ctx.PreState.NsKVMp[tx.ContractId.Name]; !ok {
//		ctx.PreState.NsKVMp[tx.ContractId.Name] = make(map[string]*ledger.NsKV)
//	} else {
//		ctx.PreState.NsKVMp[tx.ContractId.Name][ContractVersionSpace+"State"] = verNskv
//	}
//	return nil
//}
//func createContract(tx *ledger.Transaction, ctx *VMRunContext) (bool, string, error) {
//	log := w.log
//	var payLoadList []interface{}
//	err := rlp.DecodeBytes(tx.Payload, &payLoadList)
//	if err != nil {
//		return true, "", errors.New("Decode rlp bytes to list failed " + err.Error())
//	}
//	code := payLoadList[0].([]byte)
//	//Check合约代码是否合法
//	ct := common.Contract{Code: code}
//	pass, rst, _ := w.checkContract(code)
//	if !pass {
//		log.Errorf("Create contract failed,contract content checked failed,rst = %d", rst)
//		return false, "", nil
//	}
//	//生成智能合约地址contractId+version
//	newAddress := tx.GetContractAddressById()
//	ctIns := contract.GetContractInstance()
//	ctNew, _ := ctIns.GetContract(newAddress)
//	if ctNew != nil {
//		//不能部署Name和Version都相同的contract
//		return true, "", errors.New("Contract already exist ")
//	}
//
//	//执行合约初始化
//	ct.Address = newAddress
//	ct.ContractId = tx.ContractId
//	bytes, err := proto.Marshal(&ct)
//	if err == nil && w.cache != nil {
//		w.cache.Set(newAddress, bytes)
//	}
//
//	bl := w.jvmIns.BootLoader
//	groupedTx := ctx.GroupedTx
//	var mainClass string
//	if bl != nil {
//		mainClass = bl.GetMainContractClass(ct.Code)
//		if mainClass == "" {
//			groupedTx.TxExecRst.Receipt.TxStatus = ledger.TransactionReceipt_CALL_CONTRACT_ERROR
//			return true, "", errors.New("main class not found")
//		}
//	} else {
//		groupedTx.TxExecRst.Receipt.TxStatus = ledger.TransactionReceipt_CALL_CONTRACT_ERROR
//		return true, "", errors.New("jvm bootloader is nil")
//	}
//	//调用jvm执行
//	ctx.ContractAccount = &common.Account{Type: common.Account_CONTRACT, InternalAddress: tx.ContractId.Name}
//	ctx.ContractAddress = newAddress
//	w.jvmIns.StartJVM8(mainClass, tx.Payload, w.log, ctx)
//	return true, newAddress, nil
//}
//
//func callContract(tx *ledger.Transaction, ctx *VMRunContext) error {
//	log := w.log
//	contractAccount := ctx.ContractAccount
//	groupedTx := ctx.GroupedTx
//	//外部账户转给合约账户
//	if tx.Value > 0 {
//		contractAccount.Balance += tx.Value
//	}
//	toAddr := ctx.ContractAddress
//	args := tx.Payload
//	//获取智能合约代码
//	//先查找本地cache
//	var ctBytes []byte
//	var err error
//	var ct *common.Contract
//	if w.cache != nil {
//		ctBytes, err = w.cache.Get(toAddr)
//	}
//	if err != nil || len(ctBytes) == 0 {
//		ins := contract.GetContractInstance()
//		ct, err = ins.GetContract(toAddr)
//		if err != nil {
//			log.Errorf("Get contract failed %v", err)
//			return err
//		}
//		//fmt.Println(hex.EncodeToString(ct.Code))
//
//	} else {
//		var result common.Contract
//		err = proto.Unmarshal(ctBytes, &result)
//		if err != nil {
//			return err
//		}
//		ct = &result
//	}
//	if ct != nil {
//		//合约状态不正常
//		var bytes []byte
//		bytes, err = proto.Marshal(ct)
//		if err == nil && w.cache != nil {
//			w.cache.Set(toAddr, bytes)
//		}
//		//mainClass := ct.ContractId.Name
//		if ct.Code == nil || len(ct.Code) == 0 {
//			groupedTx.TxExecRst.Receipt.TxStatus = ledger.TransactionReceipt_CALL_CONTRACT_ERROR
//			return errors.New("contract code is nil")
//		}
//		bl := w.jvmIns.BootLoader
//		var mainClass string
//		if bl != nil {
//			mainClass = bl.GetMainContractClass(ct.Code)
//			if mainClass == "" {
//				groupedTx.TxExecRst.Receipt.TxStatus = ledger.TransactionReceipt_CALL_CONTRACT_ERROR
//				return errors.New("main class not found")
//			}
//		} else {
//			groupedTx.TxExecRst.Receipt.TxStatus = ledger.TransactionReceipt_CALL_CONTRACT_ERROR
//			return errors.New("jvm bootloader is nil")
//		}
//		//调用jvm执行
//		w.jvmIns.StartJVM8(mainClass, args, w.log, ctx)
//		return nil
//	}
//	return errors.New("contract is not exsit")
//}
